#pragma once

#include "Poco/DirectoryIterator.h"
#include "Poco/Exception.h"
#include "Poco/File.h"
#include "Poco/Path.h"
#include "cppmicroservices/Framework.h"
#include "cppmicroservices/FrameworkFactory.h"
#include "cppmicroservices/em/EventAdmin.hpp"
#include "usk_ldap_filter.hpp"

#include <memory>
#include <set>
#include <string>
#include <unordered_set>


using namespace cppmicroservices;

namespace usk {
    namespace core {
        class OsgiPrivate : public std::enable_shared_from_this<OsgiPrivate> {
        public:
            using ACCESS_EXPIRED_TOPIC_CACHE_MAP =
                    Poco::AccessExpireLRUCache<std::string, std::shared_ptr<LDAPFilter>>;
            ;
            OsgiPrivate() {
                FrameworkFactory factory;
                frame_work_ = std::make_shared<Framework>(factory.NewFramework());
            }

            static bool IsSharedLibrary(const std::string &path) {
                // 获取文件扩展名（转换为小写）
                std::string ext = Poco::Path(path).getExtension();
                std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

                // 定义动态库扩展名集合
                static const std::set<std::string> library_exts = {
                        "dll", // Windows
                        "so", // Linux
                        "dylib" // macOS
                };


                return library_exts.find(ext) != library_exts.end();
            }

            bool AddBundleInstallPath(const char *path) {
                const Poco::File file(path);
                if (!file.exists()) {
                    // 路径不存在
                    return false;
                }
                if (install_bundle_files_.find(path) != install_bundle_files_.end()) {
                    // 文件已经添加到集合
                    return false;
                }
                if (file.isFile()) {
                    if (IsSharedLibrary(path)) {
                        install_bundle_files_.insert(path);
                        return true;
                    }
                    return false;
                }
                if (file.isDirectory()) {
                    try {
                        Poco::DirectoryIterator it(file);
                        Poco::DirectoryIterator end;
                        while (it != end) {
                            AddBundleInstallPath(it->path().c_str());
                            ++it;
                        }
                    } catch (const Poco::Exception &e) {
                        return false;
                    }
                }
                return true;
            }

        public:
            /// @brief cppmicroservices框架对象
            std::shared_ptr<Framework> frame_work_;

            /// @brief 准备/已安装的bundle文件路径集合
            std::unordered_set<std::string> install_bundle_files_;

            /// @brief 默认的日志服务对象
            std::shared_ptr<LogService> log_service_;
            ServiceRegistration<LogService> log_service_registration_;

            /// @brief 默认的事件通知服务对象
            std::shared_ptr<EventAdmin> event_admin_;
            ServiceRegistration<EventAdmin> event_admin_registration_;
        };
    } // namespace core
} // namespace usk
